package com.yy.train.ticket.train.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yy.train.ticket.goout.st.SeatTicket;
import com.yy.train.ticket.train.dao.TtLineStationDao;
import com.yy.train.ticket.train.dao.TtTicketDao;
import com.yy.train.ticket.train.dao.TuOrderDao;
import com.yy.train.ticket.train.dao.TuRideDao;
import com.yy.train.ticket.train.entity.TtTicketEntity;
import com.yy.train.ticket.train.entity.TuOrderEntity;
import com.yy.train.ticket.train.service.TuOrderService;
import com.yy.train.ticket.utils.R;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.stream.Collectors;


@Service("tuOrderService")
public class TuOrderServiceImpl extends ServiceImpl<TuOrderDao, TuOrderEntity> implements TuOrderService {

    @Resource
    TuOrderDao tuOrderDao;
    @Resource
    TtLineStationDao ttLineStationDao;
    @Resource
    TuRideDao tuRideDao;
    @Resource
    TtTicketDao ttTicketDao;

    @Override
    public R buyTicket(Long ticketId) {
        TtTicketEntity ttTicketEntity=this.ttTicketDao.selectById(ticketId);
        Long numberId = ttTicketEntity.getNumberId();
        TuOrderEntity tuOrderEntity = new TuOrderEntity();
        tuOrderEntity.setTicketId(ttTicketEntity.getTicketId());
        tuOrderEntity.setSeatId(ttTicketEntity.getSeatId());
        tuOrderEntity.setNumberId(numberId);
        tuOrderEntity.setRunDate(ttTicketEntity.getRunDate());
        tuOrderEntity.setRunDateId(ttTicketEntity.getRunDateId());
        int i =  this.ttTicketDao.update(null, Wrappers.<TtTicketEntity>lambdaUpdate().set(TtTicketEntity::getSell, 1).eq(TtTicketEntity::getTicketId, ticketId).eq(TtTicketEntity::getSell, 0));
       // int i =2;
        if (i > 0) {
            tuOrderDao.insert(tuOrderEntity);
            return R.ok();
        } else {
            return R.error("已经售卖");
        }

    }
    public R buyTicket1(TtTicketEntity ttTicketEntity) {
        Long ticketId = ttTicketEntity.getTicketId();
        Long numberId = ttTicketEntity.getNumberId();
        TuOrderEntity tuOrderEntity = new TuOrderEntity();
        tuOrderEntity.setTicketId(ttTicketEntity.getTicketId());
        tuOrderEntity.setSeatId(ttTicketEntity.getSeatId());
        tuOrderEntity.setNumberId(numberId);
        tuOrderEntity.setRunDate(ttTicketEntity.getRunDate());
        tuOrderEntity.setRunDateId(ttTicketEntity.getRunDateId());
        int i = this.ttTicketDao.update(null, Wrappers.<TtTicketEntity>lambdaUpdate()
                .set(TtTicketEntity::getSell, 1).
                eq(TtTicketEntity::getTicketId, ticketId));
        tuOrderDao.insert(tuOrderEntity);
        return R.ok();


    }
    @Override
    public   R shop(TtTicketEntity ttTicketEntity) {


        List<TtTicketEntity> list = this.ttTicketDao.selectList(Wrappers.<TtTicketEntity>lambdaQuery().eq(TtTicketEntity::getRunDateId, ttTicketEntity.getRunDateId()).eq(TtTicketEntity::getNumberId, ttTicketEntity.getNumberId()).eq(TtTicketEntity::getSell, 0).eq(TtTicketEntity::getStartStationId, ttTicketEntity.getStartStationId()).eq(TtTicketEntity::getEndStationId, ttTicketEntity.getEndStationId()));
        if (!list.isEmpty()) {
            return buyTicket(list.get(0).getTicketId());
        }
        return R.error("没有车票了！！！");
    }

    private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();

    private final Lock readLock = lock.readLock();

    private final Lock writeLock = lock.writeLock();
    @Override
    public   R shop1(TtTicketEntity ttTicketEntity) {
        List<TtTicketEntity> list;
        try{
            readLock.lock();
         list = this.ttTicketDao.selectList(Wrappers.<TtTicketEntity>lambdaQuery().eq(TtTicketEntity::getRunDateId, ttTicketEntity.getRunDateId()).eq(TtTicketEntity::getNumberId, ttTicketEntity.getNumberId()).eq(TtTicketEntity::getSell, 0).eq(TtTicketEntity::getStartStationId, ttTicketEntity.getStartStationId()).eq(TtTicketEntity::getEndStationId, ttTicketEntity.getEndStationId()));

        }finally{
            readLock.unlock();
        }
        if (!list.isEmpty()) {
            writeLock.lock();
            try {
                return buyTicket1(list.get(0));
            } finally {
                writeLock.unlock();
            }
        }
        return R.error("没有车票了！！！");
    }

    @Override
    public R buySectionTicket(TtTicketEntity ttTicketEntity) {
        Long numberId = ttTicketEntity.getNumberId();
        Long sectionId = ttTicketEntity.getSectionId();
        Long runDateId = ttTicketEntity.getRunDateId();
        List<SeatTicket> list=   this.ttTicketDao.seatTicket(ttTicketEntity);
        Map<Long, List<SeatTicket>> listMap = list.stream().collect(Collectors.groupingBy(SeatTicket::getRunSeatId));
        Iterator<Map.Entry<Long, List<SeatTicket>>> iterator = listMap.entrySet().iterator();
        Long ticketId = null;
        long num=Integer.MAX_VALUE;
        while (iterator.hasNext()){
            Map.Entry<Long, List<SeatTicket>> next = iterator.next();
            Long runSeatId=next.getKey();
            List<SeatTicket> list1=next.getValue();
            System.out.println("key="+next.getKey()+"value="+next.getValue());
            for (SeatTicket st:list1
                 ) {
                Long sectionId1 = st.getSectionId();
                if (Objects.equals(sectionId1,sectionId)) {
                    long count = list1.stream()
                            .filter(e -> Objects.equals(e.getSell(),0))
                            .count();
                    if (count<num){
                        num=count;
                        ticketId= st.getTicketId();
                    }
                }
            }
        }

        return buyTicket(ticketId);

    }

}